//==========================================================================
// Copyright (c) 2000-2008,  Elastos, Inc.  All Rights Reserved.
//==========================================================================

#ifndef __ELASTOS_MC146818_H__
#define __ELASTOS_MC146818_H__

enum {
    RTCPort_AddressRegister         = 0x70,
    RTCPort_DataRegister            = 0x71,
};

enum {
    // Clock or Calendar
    RTCRegister_CurrenSecond        = 0x00,
    RTCRegister_AlarmSecond         = 0x01,
    RTCRegister_CurrentMinute       = 0x02,
    RTCRegister_AlarmMinute         = 0x03,
    RTCRegister_CurrentHour         = 0x04,
    RTCRegister_AlarmHour           = 0x05,
    RTCRegister_CurrentDayOfWeek    = 0x06,     // 1 = Sunday
    RTCRegister_CurrentDateOfMonth  = 0x07,
    RTCRegister_CurrentMonth        = 0x08,
    RTCRegister_CurrentYear         = 0x09,     // final two digits. eg, 93

    // status
    RTCRegister_StatusA             = 0x0a,
    RTCRegister_StatusB             = 0x0b,
    RTCRegister_StatusC             = 0x0c,
    RTCRegister_StatusD             = 0x0d,

    // Configuration
    RTCRegister_Century             = 0x32,
};

// Status Register A (Read/Write except UIP)
#define SRA_UIP      __8BIT(7)  // UIP flag, Update In Progress. When set an
                                // update cycle is in progress and the
                                // clock/calendar cannot be accessed. When
                                // clear, at least 244 microseconds are
                                // available to access clock/calendar bytes
                                // (it's plenty of time even on 6MHz AT).

// Status Register B (Read/Write)
#define SRB_SET     __8BIT(7)   // when set to 1, any update in progress is
                                // aborted and a program may initialize the
                                // clock/calendar/alarm bytes without an update
                                // occurring. Setting this bit clears UIE
                                // (bit 4). Clearing bit 7 allows the update
                                // cycle to continue.

#define SRB_PIE     __8BIT(6)   // Periodic Interrupt Enable, when set the
                                // periodic interrupt will occur at the
                                // frequency specified by RS bits in Status
                                // Register A.

#define SRB_AIE     __8BIT(5)   // Alarm Interrupt Enable, when set the alarm
                                // interrupt will be asserted once for each
                                // second that the current time matches the
                                // alarm time.

#define SRB_UIE     __8BIT(4)   // Update-ended Interrupt Enable, when set the
                                // update-ended interrupt will be asserted once
                                // each second after the end of update cycle.
                                // This bit is cleared when SET bit goes high
                                // but it is not reset when SET is cleared.

#define SRB_SQWE    __8BIT(3)   // Square Wave Enable, when set, enables the
                                // square wave output on the SQW pin at the
                                // frequency specified by the RS bits in the
                                // Status Register A. The SQW pin is not
                                // connected to anything in the AT.

#define SRB_DM      __8BIT(2)   // Data Mode, indicates mode for clock/calendar
                                // data: 0 = BCD and 1 = binary, BIOS setting
                                // is 0.

#define SRB_24H     __8BIT(1)   // controls hours byte, 0 = 12-hour and
                                // 1 = 24-hour format, BIOS setting is 1.

#define SRB_DSE     __8BIT(0)   // Daylight Savings Enable

INLINE uint8_t ReadRTC(uint8_t u8Address)
{
    OutbDelay(RTCPort_AddressRegister, u8Address);
    return Inb(RTCPort_DataRegister);
}

INLINE void WriteRTC(uint8_t u8Address, uint8_t u8Data)
{
    OutbDelay(RTCPort_AddressRegister, u8Address);
    Outb(RTCPort_DataRegister, u8Data);
}

#endif // __ELASTOS_MC146818_H__
